
import mqtt from 'mqtt';
import moment from 'moment';
// import db from './mysqlHelper.js';
import config from './configuration.js';


let askArray = [];
const CMD_TIMEOUT = 5000; //5秒超时

let cmd_map = new Map();




let mq_client = mqtt.connect(`mqtt://${config.mqttConfig.host}:${config.mqttConfig.port}`, {
    username: config.mqttConfig.username, password: config.mqttConfig.password, clientId: moment().unix(),
    keepalive: 60, clean: true
});
mq_client.on('connect', async () => {
    console.log(`与MQTT服务器的连接成功`);
    console.log(`订阅主题 /sys/WG585OWAN24120602015/up`);
    mq_client.subscribe(`/sys/+/+`);

})

function boolToNumber(bool) {
    if (bool) {
        return 1;
    }
    else {
        return 0;
    }
}

mq_client.on('message', async (topic, message) => {
    let strMessage = message.toString();
    console.log(`接收到MQTT服务器的消息`, topic, strMessage);
    let rec_obj = null;
    try {
        rec_obj = JSON.parse(strMessage);
    } catch (error) {
        console.log('数据解析失败', error.message, strMessage);
        return;
    }
    console.log('接收到的数据', rec_obj);



})
mq_client.on('error', (err) => {
    console.log(`与MQTT服务器的连接出错`, err.message);
})
mq_client.on('close', () => {
    console.log(`与MQTT服务器的连接关闭`);
});

async function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, ms);
    });
}

//清除超时没有删除的指令
async  function cleanExpriredCmd() {
    let now = moment();
    cmd_map.forEach((value, key) => {
        if (now.isAfter(value.time_out)) {
            cmd_map.delete(key);
        }
    })
}

//一次读取一台设备所有的寄存器
async function readDeviceAllReg(deviceId) {
    let topic = `/${deviceId}/down`;
    let req = moment().unix().toString();
    let msg = {
        cmdId: moment().unix(),
        devSn: deviceId,
        req
    };
    console.log(`发送消息`, topic, msg);
    let time_out = moment().add(CMD_TIMEOUT, 'ms');
    mq_client.publish(topic, JSON.stringify(msg), { qos: 1, retain: false }, (err) => {
        if (err) {
            console.log('发送失败', err.message);
        } else {
            console.log('发送成功');
            cmd_map.set(req, {time_out, ask:null});
        }
    });

    let rec_obj = null;
    while (moment().isBefore(time_out) && rec_obj == null) {
        let res = cmd_map.get(req);
        if (res.ask != null) {
            cmd_map.delete(req);
            rec_obj = res.ask;
        }
        await sleep(100);
    }
    if (rec_obj == null) {
        cmd_map.delete(req);
        console.log('指令执行超时', req);
        return {code:0, msg:'指令执行超时'};
    }
    return {code:1, data: rec_obj};



}
//一次读取一台设备的多个指定寄存器

async function readDeviceReg(deviceId, regArr) {
    let topic = `/${deviceId}/down`;
    let req = moment().unix().toString();
    let msg = {
        cmdId: 85,
        devSn: deviceId,
        varList: regArr,
        req
    };
    console.log(`发送消息`, topic, msg);
    let time_out = moment().add(CMD_TIMEOUT, 'ms');
    mq_client.publish(topic, JSON.stringify(msg), { qos: 1, retain: false }, (err) => {
        if (err) {
            console.log('发送失败', err.message);
        } else {
            console.log('发送成功');
            cmd_map.set(req, {time_out, ask:null});
        }
    });

    let rec_obj = null;
    while (moment().isBefore(time_out) && rec_obj == null) {
        let res = cmd_map.get(req);
        if (res.ask != null) {
            cmd_map.delete(req);
            rec_obj = res.ask;
        }
        await sleep(100);
    }
    if (rec_obj == null) {
        cmd_map.delete(req);
        console.log('指令执行超时', req);
        return {code:0, msg:'指令执行超时'};
    }
    return {code:1, data: rec_obj};
}

//写入数据到指定寄存器 
async function writeDeviceReg(deviceId, regName, regValue) {
    let topic = `/${deviceId}/down`;
    let req = moment().unix().toString();
    let msg = {
        cmdId:87,
        devSn: deviceId,
        varList:JSON.parse(`[{"${regName}":${regValue}}]`),
        req
    };
    console.log(`发送消息`, topic, msg);
    let time_out = moment().add(CMD_TIMEOUT, 'ms');
    mq_client.publish(topic, JSON.stringify(msg), { qos: 1, retain: false }, (err) => {
        if (err) {
            console.log('发送失败', err.message);
        } else {
            console.log('发送成功');
            cmd_map.set(req, {time_out, ask:null});
        }
    });

    let rec_obj = null;
    while (moment().isBefore(time_out) && rec_obj == null) {
        let res = cmd_map.get(req);
        if (res.ask != null) {
            cmd_map.delete(req);
            rec_obj = res.ask;
        }
        await sleep(100);
    }
    if (rec_obj == null) {
        cmd_map.delete(req);
        console.log('指令执行超时', req);
        return {code:0, msg:'指令执行超时'};
    }
    return {code:1, data: rec_obj};
}



